using System;
using Project.Library.Core.DBC.Exceptions;

namespace Project.Library.Core.DBC
{
    /// <summary>
    /// Design by contract checks
    /// </summary>
    public static class Checks
    {
        #region Require

        /// <summary>
        /// Precondition check - should run regardless of preprocessor directives.
        /// </summary>
        public static void Require(bool assertion, string message)
        {
            if (!assertion) throw new PreconditionException(message);
        }

        /// <summary>
        /// Precondition check - should run regardless of preprocessor directives.
        /// </summary>
        public static void Require(bool assertion, string message, Exception inner)
        {
            if (!assertion) throw new PreconditionException(message, inner);
        }

        /// <summary>
        /// Precondition check - should run regardless of preprocessor directives.
        /// </summary>
        public static void Require(bool assertion)
        {
            if (!assertion) throw new PreconditionException();
        }

        #endregion

        #region Ensure

        /// <summary>
        /// Postcondition check.
        /// </summary>
        public static void Ensure(bool assertion, string message)
        {
            if (!assertion) throw new PostconditionException(message);
        }

        /// <summary>
        /// Postcondition check.
        /// </summary>
        public static void Ensure(bool assertion, string message, Exception inner)
        {
            if (!assertion) throw new PostconditionException(message, inner);
        }

        /// <summary>
        /// Postcondition check.
        /// </summary>
        public static void Ensure(bool assertion)
        {
            if (!assertion) throw new PostconditionException();
        }

        #endregion

        #region Invariant

        /// <summary>
        /// Invariant check.
        /// </summary>
        public static void Invariant(bool assertion, string message)
        {
            if (!assertion) throw new InvariantException(message);
        }

        /// <summary>
        /// Invariant check.
        /// </summary>
        public static void Invariant(bool assertion, string message, Exception inner)
        {
            if (!assertion) throw new InvariantException(message, inner);
        }

        /// <summary>
        /// Invariant check.
        /// </summary>
        public static void Invariant(bool assertion)
        {
            if (!assertion) throw new InvariantException();
        }

        #endregion

        #region Assert

        /// <summary>
        /// Assertion check.
        /// </summary>
        public static void Assert(bool assertion, string message)
        {
            if (!assertion) throw new AssertionException(message);
        }

        /// <summary>
        /// Assertion check.
        /// </summary>
        public static void Assert(bool assertion, string message, Exception inner)
        {
            if (!assertion) throw new AssertionException(message, inner);
        }

        /// <summary>
        /// Assertion check.
        /// </summary>
        public static void Assert(bool assertion)
        {
            if (!assertion) throw new AssertionException();
        }

        #endregion
    }
}